<HTML><HEAD><TITLE>session_transaction(++Session, +Goal)</TITLE>
</HEAD><BODY>[ <A HREF="index.html">library(dbi)</A> | <A HREF="../../index.html">Reference Manual</A> | <A HREF="../../fullindex.html">Alphabetic Index</A> ]
<H1>session_transaction(++Session, +Goal)</H1>
executes Goal as a database transaction.
<DL>
<DT><EM>Session</EM></DT>
<DD>A session handle
</DD>
<DT><EM>Goal</EM></DT>
<DD>Prolog goal that implements a database update.
</DD>
</DL>
<H2>Description</H2>
<P>
 This executes Goal as a database transaction. This predicate is only useful
 if the database supports transactions (i.e. changes are local until committed).
 If Goal succeeds session_transaction/2  commits the update, cuts any
 alternative solutions to Goal and succeeds itself.
</P><P>
 If Goal fails or causes a database error, session_transaction/2 fails and
 rolls back any changes done to the database.
</P><P>
 If Goal aborts, the update is rolled back, and session_transaction/2 aborts.
</P><P>
 MySQL specific note: transactions are supported for transactional tables only
 (i.e. stored with a storage engine with transaction-safe capabilities).
</P><P?
 NOTE: It is a programming error to have some previous uncommitted
 database updates at the time of calling session_transaction/2. 
</P><P>
 Calls of this predicate can be nested, but only the outermost transaction 
 is real. All the inner transactions are simply equivalent to call(Goal).
 This way it is possible to write a call to session_transaction/2, into 
 some code that implements a simple update, but then to include that simple 
 update into a larger transaction.
</P><P>
 Similarly session_commit/1 and session_rollback/1 alter their behaviour so
 that they can be used within a transaction.
</P><P>
 Transactions are local to one session so there is no way to safely make an 
 update relating to several sessions.
<H3>Modules</H3>
This predicate is sensitive to its module context (tool predicate, see @/2).
<H3>Exceptions</H3>
<DL>
<DT><EM>(5) type error </EM>
<DD>Session is not a valid session handle
<DT><EM>(abort) </EM>
<DD>session_rollback/1 called within Goal
</DL>
<H2>Examples</H2>
<PRE>
transfer(Session, Amount,FromAccount,ToAccount) :-
     session_transaction(Session, 
         transfer_(Session,Amount,FromAccount,ToAccount)
     ).

% note '?' in SQL in the syntax MySQL uses for placeholders. This may be
% different in other DBMS
transfer_(Session, Amount, FromAccount, ToAccount) :-
    SQL = "update accounts set balance = balance + ? \
                                             where id = ?",
    Deduct is - Amount,
    session_sql_prepare(Session,incbal(1.0,12),SQL,1,Update),
    cursor_next_execute(Update,incbal(Deduct,FromAccount)),
    cursor_next_execute(Update,incbal(Amount,ToAccount)).
</PRE>
<H2>See Also</H2>
<A HREF="../../lib/dbi/session_rollback-1.html">session_rollback / 1</A>, <A HREF="../../lib/dbi/session_commit-1.html">session_commit / 1</A>
</BODY></HTML>
